package com.ruoyi.aitapp.utils;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.aitcommon.config.ConfigManager;
import com.ruoyi.aitcommon.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;

@Component
@DependsOn("configManager")  // 确保这个组件在 ConfigManager 之后初始化
public class APPConfigUtils {
    @Autowired
    ConfigManager configManager;
    final String APP_PARAMS="appconfig.system.sysParams";
    final String APP_PAGES="appconfig.pages.pages";
    final String APP_PARAM_PREFIX = "appParams";

    /**
     * 类加载执行
     */
    @PostConstruct
    public void init() throws Exception {
        //APP 系统参数构造
        this.buildParam();
    }
    public void buildParam() throws Exception {
        if(configManager.hasContextByParm(APP_PARAMS)){
            final Object contextByParm = configManager.getContextByParm(APP_PARAMS);
            final Map<String, Object> context = configManager.getContext();
            JSONArray sysParams = (JSONArray) contextByParm;
            for (int i = 0; i < sysParams.size(); i++) {
                JSONObject item = sysParams.getJSONObject(i);
                String code = APP_PARAM_PREFIX+'.'+item.getString("code");
                final String value = item.getString("value");
                LogUtils.info("APPParamManager设置参数[{}],值[{}]",code,value);
                MapUtils.putPathObject(code,context, value);
            }
        }
    }
    public boolean isAppParam(String parm){
        return parm.startsWith(APP_PARAMS);
    }

    /**
     * 将菜单按照分组方式重新构造菜单集合
     * @param permMenus 菜单集合
     * @return
     */
    public JSONArray getMenuGroups(List<Object> permMenus) throws Exception {
        JSONArray groups1=new JSONArray();
        if(ObjUtils.isNotBlank(permMenus)){
            //按照group/menu分组格式,重新构造授权菜单集合JSON对象
            final Map<String, Object> permMap = MapUtils.newMap1(permMenus);
            final String groupPath="appconfig.menus.groups";
            final Object groups = configManager.getContextByParm(groupPath);
            for (Object group : (JSONArray)groups) {
                final JSONObject groupJSON = (JSONObject) group;
                if(!groupJSON.getBoolean("show")) continue;//不显示
                final JSONArray menus = groupJSON.getJSONArray("menus");
                final JSONArray newMenus=new JSONArray();
                for(Object menu : menus){
                    final JSONObject menuJSON = (JSONObject)menu;
                    if(!menuJSON.getBoolean("show")) continue;//不显示
                    if(permMap.containsKey("*")){
                        // * 授权所有菜单
                        newMenus.add(menu);
                    } else if(permMap.containsKey(menuJSON.getString("code"))){
                        // 授权菜单
                        newMenus.add(menu);
                    }
                }
                if(ObjUtils.isNotBlank(newMenus)){
                    //如果授权菜单非空,则添加进授权菜单集合至新菜单分组
                    JSONObject group1=ObjUtils.deepClone(group,JSONObject.class);
                    group1.put("menus",newMenus);
                    groups1.add(group1);
                }
            }
        }
        ExceptionUtils.checkBlankOrUndefined(groups1,"授权菜单为空");
        //对菜单进行翻译
        final JSONArray ret1 = (JSONArray)JSONParamUtils.transParamsJSON(groups1, configManager.getContext());
        return ret1;
    }

    /**
     * 依据用户获取授权菜单列表
     * @param userCode
     * @return
     */
    public List<Object> getPermMenus(String userCode) throws Exception {
        JSONArray ret=new JSONArray();
        //获取用户对应角色
        List<String> roleCodes=null;
        final String userRolesParam = "appconfig.permissions.userRoles";
        final Object userRoles = configManager.getContextByParm(userRolesParam);
        ExceptionUtils.checkBlankOrUndefined(userRoles,"[{}]配置为空",userRolesParam);
        for (Object userRoleObj : (JSONArray) userRoles) {
            final JSONObject userRole = (JSONObject) userRoleObj;
            if(userCode.equals(userRole.getString("user"))){
                final JSONArray roles = userRole.getJSONArray("roles");
                roleCodes=JSONUtils.JSONArrayToList(roles,null);
            }
        }
        //依据角色,获取菜单列表
        final String rolesParam = "appconfig.permissions.roles";
        if(ObjUtils.isNotBlank(roleCodes)){
            final List<Map<String,Object>> roles = (List)configManager.getContextByParm(rolesParam);
            for (Map<String, Object> roleMap : roles) {
                //循环角色列表
                int status = roleMap.get("status")==null?0:Integer.parseInt(roleMap.get("status").toString());
                if(status==0) continue;//角色状态禁用
                final String ruleCode = roleMap.get("code").toString();
                if(roleCodes.contains(ruleCode)){
                    //将角色的菜单清单添加到返回列表中
                    for (Object menu : (JSONArray) roleMap.get("permissions")) {
                        if(!ret.contains(menu)){
                            ret.add(menu);
                        }
                    }
                }
            }
        }
        return ret;
    }
    /**
     * 依据code获取page对象
     * @param code pageCode
     * @return page对象
     */
    public Map<String, Object> getPage(String code) throws Exception {
        final List<Map<String,Object>> pages = (List)configManager.getContextByParm(APP_PAGES);
        for (Map<String, Object> page : pages) {
            if(page.get("code").equals(code)){
                return page;
            }
        }
        ExceptionUtils.throwException(null,"未找到页面配置,页面编码[{}]",code);
        return null;
    }

    /**
     * 获取翻译后的APP参数值
     * @param code 参数编码;
     * @param allowNull 是否允许为空
     * @return 参数值,翻译后
     */
    private Object getAPPParams(String code,boolean allowNull) throws Exception {
        String path=APP_PARAM_PREFIX+'.'+code;
//        加载配置
        final Object param = configManager.getContextByParm(path);
        if(!allowNull && ObjUtils.isBlank(param)){
            ExceptionUtils.throwException(null,"未找到参数配置,参数编码[{}]",code);
        }
        return param;
    }

    public int getAPPParamsInt(String code) throws Exception {
        int ret=0;
        try{
            final Object appParams = getAPPParams(code, false);
            ret = Integer.parseInt(appParams.toString());
            return ret;
        }catch (Exception ex){
            ExceptionUtils.throwException(ex,"获取参数[{}]出错",code);
        }
        return ret;
    }
    public String getAPPParamsString(String code) throws Exception {
        String ret="";
        try{
            final Object appParams = getAPPParams(code, false);
            ret = appParams.toString();
            return ret;
        }catch (Exception ex){
            ExceptionUtils.throwException(ex,"获取参数[{}]出错",code);
        }
        return ret;
    }

    public JSONObject getAPPParamsJson(String code) throws Exception {
        JSONObject ret=null;
        try{
            final Object appParams = getAPPParams(code, false);
            if(appParams instanceof Map){
                ret = new JSONObject((Map)appParams);
            }
            return ret;
        }catch (Exception ex){
            ExceptionUtils.throwException(ex,"获取参数[{}]出错",code);
        }
        return null;
    }
}
